package siclink;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.JOptionPane;

public class PassOne {

	private static int controlSectionAddress = 0x00;
	private static boolean hasControlSectionAddressBeenSet = false;
	private static String controlSectionName;
	private static int controlSectionLength;
	public static int locationCounter = 0;
	private static String DUPLICATE_SYMBOL_ERROR_CONTROL_SECTION_TABLE = "Duplicate external symbol in the Control Section Table";
	private static String DUPLICATE_SYMBOL_ERROR_SYMBOL_TABLE = "Duplicate external symbol in the Symbol Table";
	private static String FILE_READER_ERROR = "File Reader Error";
	private static String FILE_NOT_FOUND_ERROR_PART_1 = "File ";
	private static String FILE_NOT_FOUND_ERROR_PART_2 = " not found";

	public static void processFile(String source, int programAddress) throws Exception{
		if (!hasControlSectionAddressBeenSet) {
			controlSectionAddress = programAddress;
			hasControlSectionAddressBeenSet = true;
		}
		FileReader fileReader = readSourceFile(source);
		BufferedReader buffer = new BufferedReader(fileReader);
		String line;
		int address = 0x00;
		try		{
			while((line = buffer.readLine()) != null){
				if(line.equals("")) continue;
				if (line.startsWith("H")){
					controlSectionName = line.substring(1,6).trim();
					controlSectionLength = Integer.parseInt(line.substring(8).trim(), 16);					
					putControlSectionInControlSectionTable(controlSectionName, controlSectionLength);
					putSymbolNameInSymbolTable(controlSectionName, controlSectionAddress);
					locationCounter += 4;
					address = controlSectionAddress;
					controlSectionAddress += controlSectionLength;
					continue;
				}
				if (!line.startsWith("E")){
					if (line.startsWith("D")){
						int beginningIndex = 1;
						String linePart = line.substring(1).trim();
						while (!linePart.equalsIgnoreCase("")){
							putSymbolNameInSymbolTable(linePart.substring(0, 5).trim(), 
									address + (Integer.parseInt(linePart.substring(6, 12).trim(), 16)));
							locationCounter += 4;
							beginningIndex += 12;
							if (linePart.length() > 12){
								linePart = line.substring(beginningIndex).trim();
							} else {
								linePart = "";
							}
						}					
					}
				}
			}
		}
		catch (IOException e) 		{
			showErrorMessage(FILE_READER_ERROR);
		}		
	}

	private static FileReader readSourceFile(String source) throws Exception	{
		try {
			return new FileReader(source);
		}
		catch (FileNotFoundException e){
			showErrorMessage(FILE_NOT_FOUND_ERROR_PART_1 + source + FILE_NOT_FOUND_ERROR_PART_2);
			return null;
		}
	}
	public static void putControlSectionInControlSectionTable(String controlSectionName, int length) throws Exception{
		if (!SicLink.controlSectionTable.containsKey(controlSectionName)) {
			SicLink.controlSectionTable.put(controlSectionName, length);
		} else {
			showErrorMessage(DUPLICATE_SYMBOL_ERROR_CONTROL_SECTION_TABLE + " " + controlSectionName);
		}	
	}

	public static void putSymbolNameInSymbolTable(String symbolName, int address) throws Exception{
		if (!SicLink.symbolTable.containsKey(symbolName)) {
			SicLink.symbolTable.put(symbolName, address);
		} else {
			showErrorMessage(DUPLICATE_SYMBOL_ERROR_SYMBOL_TABLE + " " + symbolName);
		}	
	}	

	private static void showErrorMessage(String message) throws Exception{
		JOptionPane.showMessageDialog(null, message, "Error!",
				JOptionPane.ERROR_MESSAGE);
		System.exit(1);
	}


}